/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package EvoAlg;

/**
 *
 * @author Geost1gma
 */
public class SelectionObject {

    Algorithm alg;
    private int generation = 0;

    public static int FULL_GENERATIONAL_SHIFT = 0;
    public static int OVERPOPULATION_WITH_DEAD_PARENTS = 1;
    public static int OVERPOPULATION_WITHOUT_DEAD_PARENTS = 2;

    public SelectionObject(Algorithm alg){
        this.alg = alg;
    }

    public void fullGenerationalShift(int selection_mech){
        int popsize = alg.getPop().getPopsize();
        Population newpop = new Population(popsize);

        for (int i = 0; i < popsize; i++) {
            newpop.setIndividual(i, alg.createOffspring(selection_mech));
        }     
        alg.setPop(newpop);  
    }

    public void overpopulationAllParentsDie(int selection_mech){
        int multiplier = 2;
        int popsize = alg.getPop().getPopsize();
        int childPopsize = alg.getPop().getPopsize() * multiplier;
        Population childPop = new Population(childPopsize);
        
        for (int i = 0; i < childPop.getPop().length; i++) {
            childPop.setIndividual(i, alg.createOffspring(selection_mech));
            
        }
        alg.getProblem().Evaluate(childPop.getPop());

        Population newpop = new Population(popsize);
        
        /*for (int i = 0; i < popsize; i++) {
            alg.select_tournament(childPop);
            newpop.setIndividual(i, alg.select_tournament(childPop));            
        }*/
        newpop.setPop(findTheBestIndividuals(childPop, popsize));
        alg.setPop(newpop);
    }

    public void overpopulationCompeteWithParents(int selection_mech){
        int multiplier = 2;
        int popsize = alg.getPop().getPopsize();
        int childPopsize = alg.getPop().getPopsize() * multiplier;
        //System.out.println(childPopsize + " " + popsize );
        Population childPop = new Population(childPopsize);

        for (int i = 0; i < childPop.getPop().length; i++) {
            //System.out.println("i" + i);
            childPop.setIndividual(i, alg.createOffspring(selection_mech));
        } 

        Population childAndParents = new Population(popsize+childPopsize);
        Population newpop = new Population(popsize);
        /*
        for (int i = 0; i < popsize; i++) {
            
            newpop.setIndividual(i, alg.select_tournament(childAndParents));
        }*/
        alg.getProblem().Evaluate(childAndParents.getPop());
        
        newpop.setPop(findTheBestIndividuals(childAndParents, popsize));
        alg.setPop(newpop);
    }

    public Individual[] findTheBestIndividuals(Population pop, int desiredPopsize){
        Individual[] best = new Individual[desiredPopsize];
        Individual temp2;
        for (int i = 0; i < desiredPopsize; i++) {
            int index = 0;
            temp2 = new Individual();
            temp2.setFitness(0.0);
            for (int j = 0; j < pop.getPopsize(); j++) {
                if(pop.getIndividualAtIndex(j) != null && pop.getIndividualAtIndex(j).getFitness()>= temp2.getFitness()){
                    temp2 = pop.getIndividualAtIndex(j);
                    index= j;
                    //System.out.println(pop.getIndividualAtIndex(j).getFitness()+ " FDAFDASFASDF" + " j " + j);
                }
            }
            best[i] = temp2;
            pop.setIndividual(index, null);
            //System.out.println(best[i].getFitness() + " i " + i + "indeks" + index);
        }

        /*for (int i = 0; i < best.length; i++) {
            System.out.println(best[i].getFitness() + "2");
        }*//*
        System.out.println("-------");
        for (int i = 0; i < pop.getPopsize(); i++) {
            //System.out.println(pop.getIndividualAtIndex(i).getFitness());

        }
*/
        return best;
    }

    public double findBestFitness(){
        double max = 0.0;

        for (int i = 0; i <         alg.getPop().getPop().length; i++) {
            if(alg.getPop().getPop()[i].getFitness() > max) max = alg.getPop().getPop()[i].getFitness();
        }
        return max;
    }

    public Algorithm getAlg() {
        return alg;
    }

    public void setAlg(Algorithm alg) {
        this.alg = alg;
    }

    public int getGeneration() {
        return generation;
    }

    public void setGeneration(int generation) {
        this.generation = generation;
    }

}
